import axios, { type InternalAxiosRequestConfig, type AxiosResponse } from "axios";
import qs from "qs";
import { useUserStoreHook } from "@/store/modules/user";
import { ResultEnum } from "@/enums/ResultEnum";
import { getToken, clearToken } from "@/utils/auth";
import router from "@/router";

// 創建 axios 實例
const service = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API,
  timeout: 50000,
  headers: { "Content-Type": "application/json;charset=utf-8" },
  paramsSerializer: (params) => qs.stringify(params),
});

// 請求攔截器
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    const accessToken = getToken();
    // 如果 Authorization 設置為 no-auth，則不攜帶 Token，用於登錄、刷新 Token 等接口
    if (config.headers.Authorization !== "no-auth" && accessToken) {
      config.headers.Authorization = accessToken;
    } else {
      delete config.headers.Authorization;
    }
    const regionId = localStorage.getItem("regionId") || "0";
    if (regionId != "0") {
      config.headers.RegionId = btoa(regionId);
    }
    return config;
  },
  (error) => Promise.reject(error)
);

// 響應攔截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    // 如果響應是二進製流，則直接返回，用於下載文件、Excel 導出等
    if (response.config.responseType === "blob") {
      return response;
    }

    const { code, data, message } = response.data;
    if (code === ResultEnum.ACCESS_TOKEN_INVALID) {
      clearToken();
      console.log("handleTokenRefresh error");
      router.push("/login");
    }
    if (code === ResultEnum.SUCCESS) {
      if (data === null) {
        return response;
      }
      return data;
    }

    ElMessage.error(message || "error");
    return Promise.reject(new Error(message || "Error"));
  },
  async (error: any) => {
    // 非 2xx 狀態碼處理 401、403、500 等
    const { config, response } = error;
    if (response) {
      const { code, msg } = response.data;
      if (code === ResultEnum.ACCESS_TOKEN_INVALID) {
        // Token 過期，刷新 Token
        //return handleTokenRefresh(config);
        router.push("/login");
      } else if (code === ResultEnum.REFRESH_TOKEN_INVALID) {
        return Promise.reject(new Error(msg || "Error"));
      } else {
        ElMessage.error(msg || "API Server Request Error");
      }
    }
    return Promise.reject(error.message);
  }
);

export default service;

// 刷新 Token 的鎖
let isRefreshing = false;
// 因 Token 過期導致失敗的請求隊列
let requestsQueue: Array<() => void> = [];

// 刷新 Token 處理
async function handleTokenRefresh(config: InternalAxiosRequestConfig) {
  return new Promise((resolve) => {
    const requestCallback = () => {
      config.headers.Authorization = getToken();
      resolve(service(config));
    };

    requestsQueue.push(requestCallback);

    if (!isRefreshing) {
      isRefreshing = true;

      // 刷新 Token
      useUserStoreHook()
        .refreshToken()
        .then(() => {
          // Token 刷新成功，執行請求隊列
          requestsQueue.forEach((callback) => callback());
          requestsQueue = [];
        })
        .catch((error) => {
          console.log("handleTokenRefresh error", error);
          // Token 刷新失敗，清除用戶數據並跳轉到登錄
          ElNotification({
            title: "提示",
            message: "您的會話已過期，請重新登錄",
            type: "info",
          });
          useUserStoreHook()
            .clearUserData()
            .then(() => {
              router.push("/login");
            });
        })
        .finally(() => {
          isRefreshing = false;
        });
    }
  });
}
